<template>
	<view>
		<!-- 导航栏 -->
		<view class="flex justify-between align-center mainBgColor pos-f" style="left: 0; top: 0; right: 0; height: 44px; z-index: 9;">
			<view class="flex align-center" style="padding: 0 8px;">
				<u-icon name="arrow-left" size="21" color="#ffffff" @click="toBack()"></u-icon>
			</view>
			
			<view>
				<text class="font-16 color-white">{{ pageTitle }}</text>
			</view>
			
			<view class="flex align-center mar-r-10">
				<u-icon v-if="isEdit" name="checkbox-mark" size="20" color="#ffffff" @click="save()"></u-icon>
			</view>
		</view>
		
		<view
			class="container"
			:style="{
				height: isEdit ? `calc(80% - 44px)` : `100%`
			}"
		>
			<!-- 文字 -->
			<view class="flex mar-t-10">
				<view
					class="flex align-center justify-center font-12 color-white dis-block"
					style="width: 40px; height: 40px; border-radius: 50%;  background: #e07285;"
				>
					<text>文字</text>
				</view>
				
				<view v-if="textMsgList.length > 0" class="flex-1 mar-l-10 font-14">
					<view
						v-for="(item, index) in textMsgList"
						:key="index"
						class="bg-white border-rad-5 pad-10 mar-b-10"
						hover-class="hoverClass"
					>
						<text>{{ item.Description }}</text>
					</view>
				</view>
			</view>
			
			<!-- 图片 -->
			<view class="flex mar-t-10">
				<view
					class="flex align-center justify-center font-12 color-white"
					style="width: 40px; height: 40px; border-radius: 50%;  background: #f58b41;"
				>
					<text>图片</text>
				</view>
				
				<view v-if="pictureList.length > 0" class="flex-1 mar-l-10 font-14">
					<view
						v-for="(item, index) in pictureList"
						:key="index"
						class="flex align-center bg-white border-rad-5 pad-10 mar-b-10"
						hover-class="hoverClass"
						@click.stop="handleScaleImg(item)"
						@longpress="handleDelImg(item, index)"
					>
						<view class="w-px-80 mar-r-10">
							<image :src="item.url" mode="widthFix" class="w-100" />
						</view>
						
						<view class="flex-1" style="width: 50px; white-space: normal; overflow-wrap: break-word;">
							<text>{{ item.OriginalFileName }}</text>
						</view>
					</view>
				</view>
			</view>
		
			<!-- 语音 -->
			<view class="flex mar-t-10">
				<view
					class="flex align-center justify-center font-12 color-white"
					style="width: 40px; height: 40px; border-radius: 50%;  background: #2cb42e;"
				>
					<text>语音</text>
				</view>
				
				<view v-if="voiceList.length > 0" class="w-px-100 mar-l-10 font-14">
					<view
						v-for="(item, index) in voiceList"
						:key="index"
						class="flex align-center justify-center w-px-70 h-px-50 bg-white border-rad-5 mar-b-10"
						hover-class="hoverClass"
						@click="handlePlayVoice(item)"
					>
						<Wave :isAni="item.isPlayAudio" bg="#bd3124" />
						<!-- <text class="mar-l-5 font-16">{{ item.time }} s</text> -->
					</view>
				</view>
			</view>
			
			<!-- 视频 -->
			<view class="flex mar-t-10">
				<view
					class="flex align-center justify-center font-12 color-white"
					style="width: 40px; height: 40px; border-radius: 50%;  background: #16b58c;"
				>
					<text>视频</text>
				</view>
				
				<view v-if="videoList.length > 0" class="w-px-100 mar-l-10 font-14">
					<view
						v-for="(item, index) in videoList"
						:key="index"
						class="bg-white border-rad-5 pad-10 mar-b-10"
						hover-class="hoverClass"
					>
						<video :src="item.url" controls style="max-width: 250px;"></video>
					</view>
				</view>
			</view>
			
			<view v-if="isEdit" class="font-16 mar-t-20 font-b-800">
				<text>如果上传维修的图片，请上传整车图片，小时计，整车铭牌，故障件（铭牌、型号、条形码、故障点图片【2-3张】）</text>
			</view>
			
			<view class="flex justify-center mar-t-40 mar-b-40 color-999999">
				<text>~ 没有更多数据了</text>
			</view>
		</view>
		
		<view v-if="isEdit" class="operates">
			<view class="flex align-center justify-between mar-x-15 pad-t-10">
				<view class="flex-1 mar-r-10">
					<u--input
						v-model="text"
						placeholder="请输入内容"
						border="surround"
						height="70px"
						:customStyle="{
							background: '#ffffff',
							height: '28px'
						}"
					></u--input>
				</view>
				
				<view>
					<u-button type="primary" color="#bd3124" @click="send()">提交</u-button>
				</view>
			</view>
			
			<view class="flex align-center justify-around mar-t-20 mar-x-15">
				<view
					class="w-px-60 text-center font-14"
					@click="handleOpenPicture()"
				>
					<image src="@/static/images/media_001.png" mode="widthFix" class="w-px-40" style="pointer-events: none;" />
					<text class="dis-block color-999999">相册</text>
				</view>
				
				<view
					class="w-px-60 text-center font-14"
					@touchstart="handleTouchstart"
					@touchmove="handleTouchMove"
					@touchend="handleTouchend"
				>
					<image src="@/static/images/media_003.png" mode="widthFix" class="w-px-40" style="pointer-events: none;" />
					<text class="dis-block color-999999">按下录音</text>
				</view>
				
				<view
					class="w-px-60 text-center font-14"
					@click="handleOpenVideo()"
				>
					<image src="@/static/images/media_004.png" mode="widthFix" class="w-px-40" style="pointer-events: none;" />
					<text class="dis-block color-999999">视频</text>
				</view>
			</view>
		</view>
		
		<!-- 录音时的遮罩 -->
		<view
			v-if="isRecording"
			class="pos-a flex justify-center align-center"
			style="left: 0; right: 0; height: 100%; top: 0; background: rgba(0, 0, 0, 0.1); z-index: 99;"
		>
			<view class="flex align-center justify-center bg-white border-rad-10" style="width: 50%; height: 100px;">
				<Wave :isAni="isRecording" bg="#bd3124" />
				<text class="mar-l-10">{{ recordTime }}s</text>
				<text class="mainColor mar-l-5">录音中...</text>
			</view>
		</view>
	
		<!-- 图片放大 -->
		<CustomPopUp
			title="图片"
			closeOnClickOverlay
			:show="big.show"
			@handleCloseMask="handleCloseMask"
		>
			<view slot="content" class="pad-10">
				<view>
					<image :src="big.imgUrl" mode="widthFix" class="w-100" />
				</view>
			</view>
		</CustomPopUp>
	</view>
</template>

<script>
	import Wave from '@/components/Wave/index'
	import CustomPopUp from '@/components/CustomPopUp/index'
	import Utils from '@/utils/utils'
	import Settings from '@/utils/settings'
	
	import { mapState } from 'vuex'
	import { checkLogin, fileToBase64 } from '@/utils/lib'
	import { getUploadFileName, uploadFile } from '@/apis/common'
	import { setAttachmentInfo, delImg } from '@/apis/repairManage'
	
	export default {
		components: {
			Wave,
			CustomPopUp
		},
		
		computed: {
			...mapState({
				repairList: state => state.repair.repairList,
				token: state => state.user.token,
				longitude: state => state.user.longitude,
				latitude: state => state.user.latitude,
			})
		},
		
		data() {
			return {
				// 记录上一页是哪个字段的组件点击（具有唯一性），根据这个字段，当在当前页编辑后，返回上一页时，可以根据这个字段给点击的组件进行赋值回显
				currentField: '',
				repairOrderId: null, // 维修 id
				pageTitle: '故障描述', // 页面标题
				type: null, // 功能类型：1 单个组件（类似现场详情这种），2 多个数据列表，类似添加故障件这种
				isEdit: false, // 是否可编辑
				index: null, // 当前点击的附件的索引值，只有 type 等于 2 才有
				textMsgList: [], // 文本消息
				pictureList: [], // 图片消息
				voiceList: [], // 语音消息
				videoList: [], // 视频消息
				text: '', // 文本输入
				
				// 操作区
				operateList: [
					{ id: 1, text: '相册', imgUrl: require('@/static/images/media_001.png') },
					{ id: 2, text: '按住录音', imgUrl: require('@/static/images/media_003.png') },
					{ id: 3, text: '视频', imgUrl: require('@/static/images/media_004.png') },
				],
				
				// 录音
				isRecording: false,
				mediaRecorder: null,
				audioChunks: [],
				recordTime: 60, // 倒计时时间
				timer: null, // 倒计时实例对象
				touchX: 0, // 录音按下水平方向移动初始值
				touchY: 0, // 录音按下垂直方向移动初始值
				moveX: 0, // 录音按下水平方向移动值
				moveY: 0, // 录音按下垂直方向移动值
				isTouchTimer: null, // 按下录音按钮的计时器
				isTouchCount: 0, // 按下录音按钮的计数
				
				// 上传
				chunks: [], // 所有文件切片
				chunkSize: 102400, // 单个切片的大小
				currentChunkIndex: 0, // 上传切片的索引，默认从 0 开始
				fpos: 0, // 每次切片的大小
				
				// 查看大图
				big: {
					show: false,
					imgUrl: ''
				},
			}
		},
		
		onShow() {
			checkLogin() // 校验是否登录
		},
		
		onLoad(options) {
			this.type = parseInt(options.type) // 设置功能类型
			this.pageTitle = options.title // 设置页面标题
			
			if (options.isEdit === 'true') {
				this.isEdit = true // 可编辑
				navigator.mediaDevices.getUserMedia({ audio: true }) // 如果可以编辑，那么授权录音权限
				
				// 判断 currentField 是否存在
				if (options.currentField) {
					this.currentField = options.currentField
				}
				
				// 判断是否存在维修 repairOrderId
				if (options.repairOrderId) {
					this.repairOrderId = options.repairOrderId
				}
			} else {
				// 不可编辑
				this.isEdit = false
			}
			
			if (this.type === 2) {
				this.index = parseInt(options.index)
			}
			
			// 回显描述信息数据
			this.showData()
		},
		
		methods: {
			// 回显数据
			showData() {
				if (this.type === 1) {
					// cell 组件这种单个的从这里赋值
					this.textMsgList = JSON.parse(JSON.stringify(this.$store.state.repair.textMsgList))
					this.pictureList = JSON.parse(JSON.stringify(this.$store.state.repair.pictureList))
					this.voiceList = JSON.parse(JSON.stringify(this.$store.state.repair.voiceList))
					this.videoList = JSON.parse(JSON.stringify(this.$store.state.repair.videoList))
				} else if (this.type === 2) {
					// 添加故障件这种多个的从这里赋值
					let repairList = JSON.parse(JSON.stringify(this.repairList))
					
					repairList.forEach((item, i) => {
						if (this.index === i) {
							item.list.forEach(j => {
								if (j.prop === 'attachment') {
									this.textMsgList = j.textMsgList
									this.pictureList = j.pictureList
									this.voiceList = j.voiceList
									this.videoList = j.videoList
								}
							})
						}
					})
				}
			},
			
			// 提交
			send() {
				if (!this.text) {
					Utils.popUpMsg('error', '请输入内容', 1500)
					return
				}
				
				let msg = {
					AttachmentId: 0, // 行 id 添加时传 0
					AttachmentType: 1, // 1 文本，2 图片，4 音频，8 视频
					Description: this.text, // 文字或服务端返回的新文件名
					OriginalFileName: '', // 原始文件名
					Size: null, // 文件长度
				}
				
				this.textMsgList.push(msg)
				this.text = ''
			},
			
			// 放大图片
			handleScaleImg(row) {
				this.big.imgUrl = row.url
				this.big.show = true
			},
			
			// 点击遮罩关闭放大图片组件
			handleCloseMask() {
				this.big.show = false
				this.big.imgUrl = ''
			},
			
			// 打开相册
			handleOpenPicture() {
				// 打开相册或摄像头，选择图片
				uni.chooseImage({
					count: 1,
					sourceType: ['album', 'camera'],
					success: async (res) => {
						let file = res.tempFiles[0] // 原始文件
						
						// 获取文件名并上传文件
						Utils.loading('文件上传中...')
						
						this.handleUpload(file).then(data => {
							Utils.popUpMsg('success', data.Message, 1000)
							this.pictureList.push({
								AttachmentId: 0, // 行 id，添加时传 0
								AttachmentType: 2, // 1 文本，2 图片，4 音频，8 视频
								Description: data.fileName, // 从服务端获取到的文件名
								OriginalFileName: data.originalName, // 原始文件名
								Size: data.size, // 选择文件后的文件大小
								url: res.tempFilePaths[0], // 添加时用来回显图片的地址
							})
						}).catch(err => {
							uni.hideLoading()
						})
					},
					fail: (err) => {
						Utils.popUpMsg('none', '资源获取失败', 1500)
					}
				})
			},
			
			// 获取文件名、上传文件
			// file：原文件（未切片）
			async handleUpload(file) {
				// 第一步：选择要上传的文件，获取从服务端返回的文件名
				let result = await getUploadFileName({ fileName: file.name, token: this.token })
				let fileName = ''
				
				// 获取从后端请求得到的文件名)
				if (result) {
					fileName = result.Result.FileName
				} else {
					uni.hideLoading()
					Utils.popUpMsg('error', '获取文件名失败', 1500)
				}
				
				// 第二步：将原文件分割成一个个切片
				// 获取文件切片数量
				let count = Math.ceil(file.size / this.chunkSize)
				
				for (let i = 0; i < count; i++) {
					let chunk = file.slice(i * this.chunkSize, (i + 1) * this.chunkSize, file.type)
					chunk.name = file.name
					this.chunks.push(chunk)
				}
				
				// 记录最终上传结果
				let data = null
				
				// 第三步：如果当前上传切片一直小于总切片数量，那么就一直循环上传操作，直到所有切片完成上传
				while (this.currentChunkIndex < this.chunks.length) {
					let params = {
						originalName: file.name,
						fileName,
						fpos: this.fpos,
						TotalLength: file.size,
						token: this.token,
					}
					
					let fileBase64Url = await fileToBase64(this.chunks[this.currentChunkIndex]) // 获取文件 base64 地址
					data = await uploadFile(params, fileBase64Url)
					this.fpos += this.chunkSize
					this.currentChunkIndex ++
				}
				
				// 最后一步：上传结束，重置上传参数，返回最终上传结果
				if (this.currentChunkIndex >= this.chunks.length){
					this.fpos = 0
					this.currentChunkIndex = 0
					this.chunks = []
					uni.hideLoading()
					data.fileName = fileName // 将从服务端拿到的文件名也添加到返回的结果中
					data.originalName = file.name // 将原始文件名也添加到返回的结果中
					data.size = file.size // 将原始文件大小也添加到返回的结果中
					return data
				}
			},
			
			// 按住录音
			handleTouchstart(e) {
				// 按住按钮时的操作
				this.isTouchTimer = setInterval(() => {
					this.isTouchCount ++
					
					if (this.isTouchCount > 100) {
						// 清除定时器
						clearInterval(this.isTouchTimer)
						// 按下时间超过一百毫秒才开始录音
						this.touchX = e.touches[0].clientX
						this.touchY = e.touches[0].clientY
						this.startRecording()
					}
				}, 1)
			},
			
			// 按住录音移动时的回调
			handleTouchMove(e) {
				this.moveX = e.touches[0].clientX
				this.moveY = e.touches[0].clientY
				e.preventDefault()
			},
			
			// 松开按钮时的回调
			handleTouchend(e) {
				if (this.isTouchCount < 100){
					Utils.popUpMsg('error', '操作太快！', 1500)
				} else {
					// 松开按钮时的操作
					this.stopRecording()
					e.preventDefault()
				}
				
				// 清除定时器
				clearInterval(this.isTouchTimer)
				this.isTouchCount = 0
			},
			
			// 开始录音
			async startRecording() {
				try {
					const stream = await navigator.mediaDevices.getUserMedia({ audio: true })

					this.mediaRecorder = new MediaRecorder(stream)
					this.mediaRecorder.ondataavailable = (event) => {
						this.audioChunks.push(event.data)
					}
					
					this.mediaRecorder.onstop = async () => {
						if (60 - this.recordTime <= 1) {
							Utils.popUpMsg('error', '录音时间太短', 1500)
						} else if (this.touchY - this.moveY > 80 && this.moveY !== 0) {
							this.touchX = 0
							this.touchY = 0
							this.moveX = 0
							this.moveY = 0
							Utils.popUpMsg('error', '录音已取消', 1500)
						} else {
							let audioBlob = new Blob(this.audioChunks, { type: 'audio/mp3' })
							let blobUrl = URL.createObjectURL(audioBlob) // blob 地址
							
							// 设置语音文件名
							audioBlob.name = 'luyin_' + new Date().getTime() + '.mp3'
							
							// 获取文件名并上传文件
							Utils.loading('文件上传中...')
							
							this.handleUpload(audioBlob).then(data => {
								Utils.popUpMsg('success', data.Message, 1000)
								
								// 添加录音消息
								let obj = {
									// id: this.voiceList.length + 1, // 记录当前语音位置
									AttachmentId: 0, // 行 id，添加时传 0
									AttachmentType: 4, // 1 文本，2 图片，4 音频，8 视频
									Description: data.fileName, // 文字或服务端返回的新文件名
									OriginalFileName: data.originalName, // 原始文件名
									Size: data.size, // 文件大小
									isPlayAudio: false, // 控制语音播报
									url: blobUrl, // 添加时用来回显图片的地址
								}
								
								this.voiceList.push(obj)
								
								// 结束录音，重置倒计时
								this.recordTime = 60
							}).catch(err => {
								uni.hideLoading()
							})
						}
					
						// 结束倒计时
						if (this.timer) {
							clearInterval(this.timer)
						}
					}
					
					this.mediaRecorder.start()
					this.isRecording = true
					this.handleCountDown()
				} catch (error) {
					Utils.popUpMsg('error', '获取录音权限失败，请授权！', 1500)
				}
			},
			
			// 倒计时
			handleCountDown() {
				this.timer = setInterval(() => {
					this.recordTime --
					
					// 倒计时到 60s 自动结束语音录制
					if (this.recordTime === 0) {
						clearInterval(this.timer) // 结束倒计时
						this.stopRecording() // 结束录音
					}
				}, 1000)
			},
			
			// 停止录音
			stopRecording() {
				if (this.mediaRecorder) {
					this.mediaRecorder.stop()
					this.mediaRecorder = null
					this.audioChunks = []
					this.isRecording = false
				}
			},
			
			// 播放语音
			handlePlayVoice(row) {
				let audio = new Audio()
				
				audio.src = row.url
				row.isPlayAudio = true
				audio.play()
				
				// 记录最初的时间
				// let initTime = JSON.parse(JSON.stringify(row.time))
				
				// 倒计时
				// let time = setInterval(() => {
				// 	row.time --
					
				// 	if (row.time < 0) {
				// 		clearInterval(time)
				// 		row.time = initTime
				// 	}
				// }, 1000)
				
				// 音频结束的回调
				audio.onended = () => {
					row.isPlayAudio = false
				}
			},
			
			// 打开相机录视频
			handleOpenVideo() {
				uni.chooseVideo({
					count: 1,
					sourceType: ['album', 'camera'],
					success: async (res) => {
						let file = res.tempFile // 选中的文件
						let blobUrl = res.tempFilePath // 文件 blob 地址
						
						// 获取文件名并上传文件
						Utils.loading('文件上传中...')
						
						this.handleUpload(file).then(data => {
							Utils.popUpMsg('success', data.Message, 1000)
							this.videoList.push({
								// id: this.voiceList.length + 1, // 记录当前语音位置
								AttachmentId: 0, // 行 id，添加时传 0
								AttachmentType: 8, // 1 文本，2 图片，4 音频，8 视频
								Description: data.fileName, // 文字或服务端返回的新文件名
								OriginalFileName: data.originalName, // 原始文件名
								Size: data.size, // 文件大小
								url: blobUrl, // 添加时用来回显图片的地址
							})
						}).catch(err => {
							uni.hideLoading()
						})
					},
					fail: (err) => {
						Utils.popUpMsg('error', '视频授权失败', 1500)
					}
				})
			},
			
			// 删除图片
			handleDelImg(row, index) {
				if (!this.isEdit) return
				
				Utils.modal('提示', '您确定删除此图片？', (res) => {
					if (res.confirm) {
						if (row.AttachmentId !== 0) {
							// 调接口删除
							Utils.loading('删除中')
							
							delImg({ id: row.AttachmentId }, this.token, this.longitude + ',' + this.latitude).then(res => {
								uni.hideLoading()
								
								// 静态删除
								this.pictureList.forEach((x, i) => {
									if (i === index) {
										this.pictureList.splice(index, 1)
									}
								})
								
								Utils.popUpMsg('success', '删除成功', 1000)
								this.$store.commit('repair/setDescInfo', { type: 2, data: this.pictureList })
							}).catch(err => {
								uni.hideLoading()
							})
						} else {
							// 静态删除
							this.pictureList.forEach((x, i) => {
								if (i === index) {
									this.pictureList.splice(index, 1)
								}
							})
							
							Utils.popUpMsg('success', '删除成功', 1000)
							this.$store.commit('repair/setDescInfo', { type: 2, data: this.pictureList })
						}
					}
				})
			},
			
			// 获取提交时的参数
			getQuerys() {
				let attachmentList = []
				let textMsgList = JSON.parse(JSON.stringify(this.textMsgList))
				let pictureList = JSON.parse(JSON.stringify(this.pictureList))
				let voiceList = JSON.parse(JSON.stringify(this.voiceList))
				let videoList = JSON.parse(JSON.stringify(this.videoList))
				
				attachmentList.push(...textMsgList)
				
				pictureList.forEach(item => {
					attachmentList.push({
						AttachmentId: item.AttachmentId,
						AttachmentType: item.AttachmentType,
						Description: item.Description,
						OriginalFileName: item.OriginalFileName,
						Size: item.Size
					})
				})
				
				voiceList.forEach(item => {
					attachmentList.push({
						AttachmentId: item.AttachmentId,
						AttachmentType: item.AttachmentType,
						Description: item.Description,
						OriginalFileName: item.OriginalFileName,
						Size: item.Size
					})
				})
				
				videoList.forEach(item => {
					attachmentList.push({
						AttachmentId: item.AttachmentId,
						AttachmentType: item.AttachmentType,
						Description: item.Description,
						OriginalFileName: item.OriginalFileName,
						Size: item.Size
					})
				})
				
				let params = {
					AttachmentList: attachmentList,
					Type: 3,
					TypeEx: 0,
					Id: this.repairOrderId
				}
				
				return params
			},
			
			// 保存故障描述信息
			async save() {
				// 保存现场描述数据
				if (this.type === 1) {
					// 设置被点击的组件字段
					if (this.currentField) {
						this.$store.commit('repair/setCurrentField', this.currentField)
					}
					
					this.$store.commit('repair/setDescInfo', { type: 1, data: this.textMsgList })
					this.$store.commit('repair/setDescInfo', { type: 2, data: this.pictureList })
					this.$store.commit('repair/setDescInfo', { type: 3, data: this.voiceList })
					this.$store.commit('repair/setDescInfo', { type: 4, data: this.videoList })
				} else if (this.type === 2) {
					let repairList = JSON.parse(JSON.stringify(this.repairList))
					
					repairList.forEach((item, i) => {
						if (this.index === i) {
							item.list.forEach(j => {
								if (j.prop === 'attachment') {
									j.textMsgList = this.textMsgList
									j.pictureList = this.pictureList
									j.voiceList = this.voiceList
									j.videoList = this.videoList
								}
							})
						}
					})
					
					this.$store.commit('repair/resetRepairComponent', repairList)
				}
				
				// repairOrderId 如果该字段存在，表示需要直接编辑当前页面信息
				if (this.repairOrderId) {
					setAttachmentInfo(this.getQuerys(), this.token, this.longitude + ',' + this.latitude).then(res => {
						Utils.popUpMsg('success', res.Message, 500)
						setTimeout(() => {
							// 保存完毕后，跳转回上一页
							uni.navigateBack({ delta: 1 })
						}, 500)
					}).catch(err => {
						console.log('提交失败！')
						console.log(err)
					})
				} else {
					// 保存完毕后，跳转回上一页
					uni.navigateBack({ delta: 1 })
				}
			},
			
			// 返回上一页
			toBack() {
				uni.navigateBack({ delta: 1 })
			},
		}
	}
</script>

<style lang="scss" scoped>
	@import "@/static/scss/variable.module.scss";
	
	.mainBgColor {
		background-color: $mainBgColor;
	}
	
	.mainColor {
		color: $mainColor;
	}
	
	// 内容部分
	.container {
		position: fixed;
		left: 0;
		right: 0;
		top: 44px;
		bottom: 0;
		background: linear-gradient(to bottom, #f5becb, #ffffff);
		overflow: auto;
		padding: 0 15px;
	}
	
	// 操作部分
	.operates {
		position: fixed;
		left: 0;
		right: 0;
		top: calc(76% + 44px);
		bottom: 0;
	}
</style>
